home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / util1 / patztdir.lha / PATZ-TDir / TDirV2_10.c < prev    next >
C/C++ Source or Header  |  1995-12-15  |  12KB  |  477 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <ctype.h>
  5. #include <dos.h>
  6. #include <exec/types.h>
  7.  
  8. #include <exec/memory.h>
  9. #include <proto/exec.h>
  10.  
  11. #include <dos/dos.h>
  12. #include <dos/rdargs.h>
  13. #include <proto/dos.h>
  14.  
  15. ///» "Program-History"
  16. /*
  17. ** Programm-History:
  18. **
  19. ** 1.0: initial release
  20. **
  21. ** 1.1: needs 3 runs through directories!!!
  22. **
  23. ** 1.2: now only 1 run :)
  24. **      added possibility to sort entries (using fix arrays of pointers; needs BIIIIG stack)
  25. **
  26. ** 2.0: changed sorting; is now performed by linked list/heap (normal stack is enough)
  27. **
  28. ** 2.1: new switch: PATZ/S -> using Patz-Font-Output-Strings ( ¬ , ¯ ) instead of " + , ` "
  29. **      use prefs-file (ENV:TDir.prefs)
  30. **      new switch: NOPREFS/S -> do not read prefs-file
  31. **
  32. ** 2.2: use ReadArgs() instead of selfmade parsing; multiple dirs possible now
  33. **      tests if dirs exist or not before calling ExamineDir() for the first time
  34. **      if no dirs are given, get name of currentdir and display it instead of ""
  35. **
  36. ** 2.3: new switch: STAT/S -> print statistic (#dirs,#files) after dir-name
  37. **
  38. ** 2.4: if file-/dir-name is too long, end it with "..." before size : file OK, dir i see no chance
  39. **      new switch: H=HELP/S prints programname and version
  40. **      new switch: N=NOTE/S prints filenote for dirs/files; NOTE: base directory gets no filenote!
  41. **
  42. ** 2.5: if file-/dir-name is too long: place "..." in the middle of name (after 5 characters)
  43. **
  44. ** 2.6: OutputName() procedure added
  45. **
  46. ** 2.7: PutNode()&GetNode() procedures added
  47. **
  48. ** 2.8: changed mode lists are ancored: now only one pointer is needed (instead of two/three)
  49. **
  50. ** 2.9: replaced printrf() by Printf(); changed 'char tree[]' to 'char *tree[]'
  51. **      place "..." in names longer than 24 chars after 'offset' characters now (instead of fixed 5)
  52. **      changed default length of filesize from 7 to 8 (filesizes from 10 to 99 MB is reasonable i think)
  53. **      restored Printf() to printf() (is needed for OutputName anyway and saved only 2 KB)
  54. **
  55. ** 2.10: some code-cleanup
  56. **
  57. */
  58. ///«
  59.  
  60.  
  61. ///» "typedef"
  62. typedef struct node {
  63.         struct node *up,*left,*right;
  64.         struct node *prev,*next;
  65.         char name[108];
  66.         char note[80];
  67.         int size; /* size<0->dir, size>=0->file */
  68.     } NODE;
  69. ///«
  70.  
  71. ///» "global variables"
  72. char *program_name="TDir 2.10";
  73. char *program_template="DIR/M,ALL/S,DIRS/S,PLAIN/S,SP=SPACE/S,S=SORT/S,NS=NOSORT/S,PATZ/S,NP=NOPREFS/S,STAT/S,H=HELP/S,N=NOTE/S";
  74. char *programmers_name="PATZ";
  75. char *version_information="\0$VER: TDir 2.10 by PATZ (20.03.95)";
  76.  
  77. short break_flag=0;
  78. int space=0,plain=0,dirs=0,all=0,sort=0,nosort=0,patz=1,stat=0,note=0;
  79. char string[256]="";
  80. char *tree[3]={"|","+","`"};
  81. ///«
  82.  
  83. ///» "prototypes"
  84. int Nope(void);
  85. int PutNode(NODE **,struct FileInfoBlock *,int);
  86. NODE * GetNode(NODE **,int);
  87. void OutputName(NODE *,int);
  88. void Swap(NODE *, NODE *);
  89. void ExamineDir(char *,char *);
  90. ///«
  91.  
  92. /* procedures */
  93. ///» "Nope"
  94. int Nope(void)
  95. {
  96.     break_flag=5;
  97.     return(0);
  98. }
  99. ///«
  100.  
  101. ///» "PutNode"
  102. int PutNode(NODE **base,struct FileInfoBlock *fib,int do_sorting)
  103. {
  104. NODE *temp=(NODE *) AllocMem(sizeof(NODE),MEMF_FAST);
  105.  
  106.     if(!temp) {
  107.         printf("%s\n","Error: No memory for entry!");
  108.         break_flag=20;
  109.         return(20);
  110.     }
  111.     temp->up=temp->left=temp->right=temp->prev=temp->next=NULL;
  112.     strcpy(temp->name,fib->fib_FileName);
  113.     strcpy(temp->note,fib->fib_Comment);
  114.     if(fib->fib_DirEntryType<0) { /* file! */
  115.         temp->size=fib->fib_Size; }
  116.     else { /* dir! */
  117.         temp->size=-1;
  118.     }
  119.     /* put new entry at right place, according to switches */
  120.     if(do_sorting) { /* Heap */
  121.         if(!(*base)) { /* CreateHeap */
  122.             (*base)=temp->up=temp->next=temp->prev=temp; }
  123.         else { /* InsertHeap */
  124.             temp->up=(*base)->up; temp->prev=(*base)->prev; temp->next=(*base);
  125.             ((*base)->prev)->next=temp; (*base)->prev=temp;
  126.             if(!((*base)->up)->left) {
  127.                 ((*base)->up)->left=temp; }
  128.             else {
  129.                 ((*base)->up)->right=temp; (*base)->up=((*base)->up)->next;
  130.             }
  131.         }
  132.         /* EstablishHeap */
  133.         while(temp!=(*base)&&stricmp((temp->up)->name,temp->name)>0) {
  134.              Swap(temp,temp->up); temp=temp->up;
  135.         } }
  136.     else { /* List */
  137.         if(!(*base)) { /* a[1] */
  138.             (*base)=temp->next=temp->prev=temp; }
  139.         else {
  140.             temp->next=(*base); temp->prev=(*base)->prev;
  141.             (temp->prev)->next=temp; (*base)->prev=temp;
  142.         }
  143.     }
  144.     return(0);
  145. }
  146. ///«
  147.  
  148. ///» "GetNode"
  149. NODE * GetNode(NODE **base,int sorted)
  150. {
  151. NODE *temp;
  152.  
  153.     if(sorted) { /* Heap */
  154.         if((*base)->next==(*base)) { /* last entry */
  155.             temp=(*base); (*base)=NULL; }
  156.         else {
  157.             Swap((*base),(*base)->prev);
  158.             temp=((*base)->prev)->up;
  159.             if(temp->right) {
  160.                 temp->right=NULL; }
  161.             else {
  162.                 temp->left=NULL;
  163.             }
  164.             /* Establish Heap */      
  165.             temp=(*base);
  166.             while(temp->left) {
  167.                 temp=temp->left;
  168.                 if((temp->up)->right&&stricmp(temp->name,(temp->next)->name)>0) {
  169.                     temp=temp->next;
  170.                 }
  171.                 if(stricmp((temp->up)->name,temp->name)<0) {
  172.                     break; }
  173.                 else {
  174.                     Swap(temp,temp->up);
  175.                 }
  176.             }
  177.             temp=(*base)->prev; (temp->prev)->next=(*base); (*base)->prev=temp->prev;
  178.         } }
  179.     else { /* Liste */
  180.         temp=(*base);
  181.         if((*base)->next==(*base)) { /* last entry */
  182.             (*base)=NULL; }
  183.         else {
  184.             (*base)=(*base)->next; (temp->prev)->next=(*base); (*base)->prev=temp->prev;
  185.         }
  186.     }
  187.     temp->up=temp->next=temp->prev=NULL;
  188.     return(temp);
  189. }
  190. ///«
  191.  
  192. ///» "OutputName"
  193. void OutputName(NODE *t, int offset)
  194. {
  195. int i;
  196.  
  197.     i=strlen(t->name);
  198.     if(i>24) {
  199.         Flush(Output());
  200.         printf("%.*s...%s",offset,t->name,t->name+(i-24+offset+3)); }
  201.     else {
  202.         printf("%-24s",t->name);
  203.     }
  204. }
  205. ///«
  206.  
  207. ///» "Swap"
  208. void Swap(NODE *a, NODE *b)
  209. {
  210. char name[108]="";
  211. char note[80]="";
  212. int size;
  213.  
  214.     strcpy(name,a->name); strcpy(note,a->note); size=a->size;
  215.     strcpy(a->name,b->name); strcpy(a->note,b->note); a->size=b->size;
  216.     strcpy(b->name,name); strcpy(b->note,note); b->size=size;
  217. }
  218. ///«
  219.  
  220. ///» "ExamineDir"
  221. void ExamineDir(char *dirname,char *dirfilenote)
  222. {
  223. BPTR currentdir;
  224. NODE *file=NULL;
  225. NODE *dir=NULL;
  226. NODE *temp=NULL;
  227. int i;
  228. int filecount=0,dircount=0,tmpfc=1,tmpdc=1;
  229. BPTR MyLock;
  230. struct FileInfoBlock *infoBlock=(struct FileInfoBlock *) AllocMem(sizeof(struct FileInfoBlock),MEMF_FAST);
  231.  
  232.     if(!infoBlock) {
  233.         printf("%s\n","Error: Can't allocate memory for FileInfoBlock!");
  234.         break_flag=20; }
  235.     else {
  236.         MyLock=Lock(dirname,ACCESS_READ);
  237.         if(!MyLock) {
  238.             printf("Error: Can't lock \"%s\"!\n",dirname);
  239.             FreeMem(infoBlock,sizeof(struct FileInfoBlock));
  240.             break_flag=20; }
  241.         else {
  242.             if(!Examine(MyLock,infoBlock)) {
  243.                 printf("%s\n","Error: Can't get infoBlock!");
  244.                 FreeMem(infoBlock,sizeof(struct FileInfoBlock));
  245.                 UnLock(MyLock);
  246.                 break_flag=20;
  247.             }
  248.         }
  249.     }
  250.  
  251.     /* read directory into arrays */
  252.     while(!break_flag&&ExNext(MyLock,infoBlock)) {
  253.         if(infoBlock->fib_DirEntryType<0) { /* file! */
  254.             filecount++;
  255.             if(!dirs) {
  256.                 PutNode(&file,infoBlock,!nosort);
  257.             } }
  258.         else { /* dir! */
  259.             dircount++;
  260.             PutNode(&dir,infoBlock,sort);
  261.         }
  262.     }
  263.  
  264.     /* print filenote of currently examined dir */
  265.     if(!break_flag&¬e) {
  266.         if(strcmp(dirfilenote,"")) {
  267.             printf("%s",string);
  268.             printf("%s",(all&&(filecount||dircount)&&!dirs)||(dirs&&dircount)?tree[0]:" ");
  269.             printf("%s",!stat?tree[2]:tree[1]);
  270.             printf("(%s)\n",dirfilenote);
  271.         }
  272.     }
  273.  
  274.     /* print statistics */
  275.     if(!break_flag&&stat) {
  276.         if(!dircount&&!filecount) {
  277.             printf("%s %s(",string,tree[2]);
  278.             if(!plain) { printf("\x9b%s","32m"); }
  279.             printf("%s","empty");
  280.             if(!plain) { printf("\x9b%s","31m"); }
  281.             printf("%s\n",")"); }
  282.         else {
  283.             printf("%s",string);
  284.             printf("%s%s(",!dirs||(dirs&&dircount)?tree[0]:" ",tree[2]);
  285.             if(dircount) {
  286.                 if(!plain) { printf("\x9b%s","32m"); }
  287.                 printf("%ld dir%s",(long) dircount,dircount>1?"s":"");
  288.                 if(!plain) { printf("\x9b%s","31m"); }
  289.             }
  290.             if(dircount&&filecount) {
  291.                 printf("%s","/");
  292.             }
  293.             if(filecount) {
  294.                 if(!plain) { printf("\x9b%s","32m"); }
  295.                 printf("%ld file%s",(long) filecount,filecount>1?"s":"");
  296.                 if(!plain) { printf("\x9b%s","31m"); }
  297.             }
  298.             printf("%s\n",")");
  299.             if(space&&dirs&&dircount) {
  300.                 printf("%s%s\n",string,tree[0]);
  301.             }
  302.         }
  303.     }
  304.  
  305.     /* process the dir-array according to switches */
  306.     while(!break_flag&&tmpdc<=dircount) {
  307.         if(space&&tmpdc!=1) {
  308.             printf("%s%s\n",string,tree[0]);
  309.         }
  310.         /* get temp from dir-array */
  311.         temp=GetNode(&dir,sort);
  312.         /* output */
  313.         printf("%s%s­­",string,(dircount==tmpdc&&(!filecount||dirs))?tree[2]:tree[1]);
  314.         if(!plain) { printf("\x9b%s","33m"); }
  315.         OutputName(temp,8);
  316.         printf("%s","        Dir");
  317.         if(!plain) { printf("\x9b%s","31m"); }
  318.         printf("%s\n","");
  319.  
  320.         if(!break_flag&&all) {
  321.             currentdir=CurrentDir(MyLock);
  322.             i=strlen(string);
  323.             string[i]=tmpdc<dircount||(filecount&&!dirs)?*tree[0]:' '; string[i+1]=' '; string[i+2]=' '; string[i+3]=0;
  324.  
  325.             ExamineDir(temp->name,temp->note);
  326.  
  327.             string[i]=0;
  328.             CurrentDir(currentdir);
  329.         }
  330.         /* free temp */
  331.         FreeMem(temp,sizeof(NODE)); temp=NULL;
  332.         tmpdc++;
  333.     }
  334.  
  335.     /* process the file-array according to switches */
  336.     if(!break_flag&&!dirs&&tmpfc<=filecount) {
  337.         if(space&&dircount&&filecount) {
  338.             printf("%s%s\n",string,tree[0]);
  339.         }
  340.         while(!break_flag&&tmpfc<=filecount) {
  341.             /* get temp from file-array */
  342.             temp=GetNode(&file,!nosort);
  343.             /* output */
  344.             printf("%s%s­",string,filecount==tmpfc?tree[2]:tree[1]);
  345.             OutputName(temp,8);
  346.             printf(" %8ld\n",(long) temp->size);
  347.  
  348.             /* print filenote of file */
  349.             if(!break_flag&¬e) {
  350.                 if(strcmp(temp->note,"")) {
  351.                     printf("%s",string);
  352.                     printf("%s  %s",tmpfc!=filecount?tree[0]:" ",tree[2]);
  353.                     printf("(%s)\n",temp->note);
  354.                 }
  355.             }
  356.  
  357.             /* free temp */
  358.             FreeMem(temp,sizeof(NODE)); temp=NULL;
  359.             tmpfc++;
  360.         }
  361.     }
  362.  
  363.     /* release memory in case of ctrl-c or other strange happenings */
  364.     if(temp) { FreeMem(temp,sizeof(NODE)); }
  365.     if(file) {
  366.         file->prev->next = NULL;
  367.         while(file) { temp=file; file=file->next; FreeMem(temp,sizeof(NODE)); }
  368.     }
  369.     if(dir) {
  370.         dir->prev->next = NULL;
  371.         while(dir) { temp=dir; dir=dir->next; FreeMem(temp,sizeof(NODE)); }
  372.     }
  373.     if(infoBlock) { FreeMem(infoBlock,sizeof(struct FileInfoBlock)); }
  374.     if(MyLock) { UnLock(MyLock); }
  375. }
  376. ///«
  377.  
  378. ///» "main"
  379. int main(int argc, char *argv[])
  380. {
  381. int i;
  382. int noprefs=0;
  383.  
  384. FILE *prefsfile;
  385. char line[108]="";
  386. char **try;
  387.  
  388. struct RDArgs *rdargs;
  389. long arg[12]={NULL,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE,DOSFALSE};
  390.  
  391. BPTR MyLock;
  392.  
  393. onbreak(Nope);
  394.  
  395.     /* do the argument parsing */
  396.     if(rdargs=ReadArgs(program_template,arg,NULL)) {
  397.         all    =(arg[1]==DOSTRUE);
  398.         dirs   =(arg[2]==DOSTRUE);
  399.         plain  =(arg[3]==DOSTRUE);
  400.         space  =(arg[4]==DOSTRUE);
  401.         sort   =(arg[5]==DOSTRUE);
  402.         nosort =(arg[6]==DOSTRUE);
  403.         patz   =(arg[7]==DOSTRUE);
  404.         noprefs=(arg[8]==DOSTRUE);
  405.         stat   =(arg[9]==DOSTRUE);
  406. /*  HELP   =(arg[10]==DOSTRUE); */
  407.         note   =(arg[11]==DOSTRUE);
  408.     }
  409.  
  410.     /* get the defaults from ENV:TDir.prefs (if file exists) */
  411.     if(!noprefs&&(prefsfile=fopen("ENV:TDir.prefs","r"))) {
  412.         i=0;while((line[i]=getc(prefsfile))!=EOF) {line[i]=toupper(line[i]); i++;}
  413.         fclose(prefsfile);
  414.         if(strstr(line,"PLAIN"))  { plain=1;  }
  415.         if(strstr(line,"SPACE"))  { space=1;  }
  416.         if(strstr(line,"DIRS"))   { dirs=1;   }
  417.         if(strstr(line,"ALL"))    { all=1;    }
  418.         if(strstr(line,"SORT"))   { sort=1;   }
  419.         if(strstr(line,"NOSORT")) { nosort=1; }
  420.         if(strstr(line,"PATZ"))   { patz=1;   }
  421.         if(strstr(line,"STAT"))   { stat=1;   }
  422.         if(strstr(line,"NOTE"))   { note=1;   }
  423.     }
  424.  
  425.     if(patz) { tree[0]="|"; tree[1]="¬"; tree[2]="¯"; }
  426.  
  427.     if(arg[10]==DOSTRUE) {
  428.         printf("%s by %s\n",program_name,programmers_name);
  429.         printf("%s\n","For details read the nonexisting docs :)\n"); }
  430.     else {
  431.         if(arg[0]) {
  432.             try=(char **)arg[0];
  433.             i=0;
  434.  
  435.             while(!break_flag&&try[i]) {
  436.                 MyLock=Lock((char *)try[i],ACCESS_READ);
  437.                 if(!MyLock) {
  438.                     printf("Can't find directory \"%s\"!\n\n",(char *)try[i]); i++;
  439.                 }
  440.                 else {
  441.                     UnLock(MyLock);
  442.     
  443.                     printf("Directory \"%s\"\n",(char *)try[i]);
  444.                     ExamineDir((char *)try[i],"");
  445.                     if(!break_flag) {
  446.                         printf("%s\n","");
  447.                     }
  448.                     i++;
  449.                 }
  450.             } }
  451.         else {
  452.             MyLock=Lock("",ACCESS_READ);
  453.             if(!MyLock) {
  454.                 printf("%s\n\n","Can't lock current directory!");
  455.                 break_flag=20; }
  456.             else {
  457.                 NameFromLock(MyLock,line,100);
  458.                 UnLock(MyLock);
  459.     
  460.                 printf("Directory \"%s\"\n",line);
  461.                 ExamineDir("","");
  462.                 if(!break_flag) {
  463.                     printf("%s\n","");
  464.                 }
  465.             }
  466.         }
  467.         if(break_flag==5) {
  468.             printf("%s\n","***Break");
  469.         }
  470.     }
  471.     
  472.     if(rdargs) { FreeArgs(rdargs); }
  473.     exit(break_flag);
  474. }
  475. ///«
  476.  
  477.